package com.example.dqhl.recycleviewdemo.view;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;

import com.example.dqhl.recycleviewdemo.R;

/**
 * Created by dell on 2017/11/15.
 */

public class NavController extends View {

    private int innerColor;//内圆
    private int outColor;//外圆

    //默认颜色
    private final static int INNE_RCOLOR_DEFAULT = Color.parseColor("#66838383");
    private final static int OUT_COLOR_DEFAULT = Color.parseColor("#55cccccc");

    private int outWidth;
    private int outHeight;

    private int realWidth;
    private int realHeight;

    private float innerCenterX;
    private float innerCenterY;

    private float outRadius;
    private float innerRedius;

    // 大小圆的画笔
    private Paint outPaint;
    private Paint innerPaint;

    private OnNavAndSpeedListener mCallBack = null;

    public interface OnNavAndSpeedListener {
        public void onNavAndSpeed(float nav, float speed);
    }


    public NavController(Context context) {
        super(context, null);
    }

    public NavController(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);

        TypedArray typedArray = context.getResources().obtainAttributes(attrs, R.styleable.NavController);
        innerColor = typedArray.getColor(R.styleable.NavController_InnerColor, INNE_RCOLOR_DEFAULT);
        outColor = typedArray.getColor(R.styleable.NavController_OutColor, OUT_COLOR_DEFAULT);
        typedArray.recycle();//用完需要回收

        // 大园 默认宽高 用dip2x 进行转化
        outHeight = dip2px(context, 100f);
        outWidth = dip2px(context, 100f);

        outPaint = new Paint();
        innerPaint = new Paint();

        outPaint.setColor(outColor);
        outPaint.setStyle(Paint.Style.FILL_AND_STROKE);

        innerPaint.setColor(innerColor);
        innerPaint.setStyle(Paint.Style.FILL_AND_STROKE);

    }


    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        int width = measureWith(widthMeasureSpec);
        int height = measureHeight(heightMeasureSpec);
        setMeasuredDimension(width, height);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);

        outRadius = Math.min(Math.min(realWidth / 2 - getPaddingLeft(), realWidth / 2 - getPaddingRight()), Math.min(realHeight / 2 - getPaddingTop(), realHeight / 2 - getPaddingBottom()));
        //画外部圆
        canvas.drawCircle(realWidth / 2, realHeight / 2, outRadius, outPaint);
        //内部圆
        innerRedius = outRadius * 0.5f;
        canvas.drawCircle(innerCenterX, innerCenterY, innerRedius, innerPaint);
    }

    /**
     * 用户在View的区域按下、移动和离开三种情况，
     * 当手指离开时我们把内圆的中心点移动到View的最中间（恢复初始状态），
     * 然后刷新，当按下或者移动时调用changeInnerCirclePosition(event)方法，
     * 这个方法用于对内圆进行处理让内圆根据手指位置判断调整位置。
     */
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                changeInnerCirclePosition(event);
                break;
            case MotionEvent.ACTION_UP:
                innerCenterX = realWidth / 2;
                innerCenterY = realHeight / 2;
                invalidate();
                break;
            case MotionEvent.ACTION_MOVE:
                changeInnerCirclePosition(event);
                break;
        }
        return true;

    }

    private void changeInnerCirclePosition(MotionEvent e) {
        //圆的方程 （x-realWidth/2）^2 +(y-realHeight/2)^2 <= outRadius^2 ??
        //确定有效的触摸点集
        float X = e.getX();
        float Y = e.getY();
        if (mCallBack != null) {
            mCallBack.onNavAndSpeed(X, Y);
        }
        boolean isPointInOutCircle = Math.pow(X - realWidth / 2, 2) + Math.pow(Y - realHeight / 2, 2) <= Math.pow(outRadius, 2);
        if (isPointInOutCircle) {
            Log.i("TAG", "inCircle");
            //两种情况：小圆半径
            boolean isPointInFree = Math.pow(X - realWidth / 2, 2) + Math.pow(Y - realHeight / 2, 2) <= Math.pow(outRadius - innerRedius, 2);
            if (isPointInFree) {
                innerCenterX = X;
                innerCenterY = Y;

                //处理限制区域，这部分使用触摸点与中心点与外圆方程交点作为内圆的中心点
                //使用近似三角形来确定这个点
                //求出触摸点，触摸点垂足和中心点构成的直角三角形（pointTri）的直角边长
                float pointTriX = Math.abs(realWidth / 2 - X);//横边
                float pointTriY = Math.abs(realHeight / 2 - Y);//竖边
                float pointTriZ = (float) Math.sqrt((Math.pow(pointTriX, 2) + Math.pow(pointTriY, 2)));
                float TriSin = pointTriY / pointTriZ;
                float TriCos = pointTriX / pointTriZ;
                //求出在圆环上的三角形的两个直角边的长度
                float limitCircleTriY = (outRadius - innerRedius) * TriSin;
                float limitCircleTriX = (outRadius - innerRedius) * TriCos;
                //确定内圆中心点的位置，分四种情况
                if (X >= realWidth / 2 && Y >= realHeight / 2) {
                    innerCenterX = realWidth / 2 + limitCircleTriX;
                    innerCenterY = realHeight / 2 + limitCircleTriY;
                } else if (X < realWidth / 2 && Y >= realHeight / 2) {
                    innerCenterX = realWidth / 2 - limitCircleTriX;
                    innerCenterY = realHeight / 2 + limitCircleTriY;
                } else if (X >= realWidth / 2 && Y < realHeight / 2) {
                    innerCenterX = realWidth / 2 + limitCircleTriX;
                    innerCenterY = realHeight / 2 - limitCircleTriY;
                } else {
                    innerCenterX = realWidth / 2 - limitCircleTriX;
                    innerCenterY = realHeight / 2 - limitCircleTriY;
                }
                Log.i("TAG", "inLimit");
            }
            invalidate();
        } else {
            Log.i("TAG", "notInCircle");
        }
    }

    public void setOnNavAndSpeedListener(OnNavAndSpeedListener listener) {
        mCallBack = listener;
    }

    public int measureWith(int widthMeasureSpec) {
        int widthMode = MeasureSpec.getMode(widthMeasureSpec);
        int widthVal = MeasureSpec.getSize(widthMeasureSpec);
        // 有三种模式
        if (widthMode == MeasureSpec.EXACTLY) {
            return widthVal + getPaddingLeft() + getPaddingRight();
        } else if (widthMode == MeasureSpec.UNSPECIFIED) {
            return OUT_COLOR_DEFAULT;
        } else {
            return Math.min(outWidth, widthVal);
        }
    }

    public int measureHeight(int heightMeasureSpec) {
        int heightMode = MeasureSpec.getMode(heightMeasureSpec);
        int heightVal = MeasureSpec.getSize(heightMeasureSpec);
        // 有三种模式
        if (heightMode == MeasureSpec.EXACTLY) {
            return heightVal + getPaddingTop() + getPaddingBottom();
        } else if (heightMode == MeasureSpec.UNSPECIFIED) {
            return OUT_COLOR_DEFAULT;
        } else {
            return Math.min(outHeight, heightVal);
        }
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        realHeight = h;
        realWidth = w;
        innerCenterX = realWidth / 2;
        innerCenterY = realHeight / 2;

    }

    public static int dip2px(Context context, float dpValue) {
        final float scale = context.getResources().getDisplayMetrics().density;
        return (int) (dpValue * scale + 0.5f);
    }
}
